\documentclass[a4paper,10pt]{article}
\usepackage[spanish]{babel} % Para división en sílabas español.
\usepackage[utf8]{inputenc} % Para poner acentos.
\usepackage{graphicx} % Paquete para ingresar gráficos
\usepackage{hyperref}
\usepackage{fancybox}

%Encabezado y Pié de página
\input{EncabezadoYPie/EncabezadoyPie.tex}
%Carátula del Trabajo
\title{ \input{Portada/Portada.tex} }

\begin{document}
	\maketitle %Hace que el título anterior sea el principal del documento
	\newpage

	\tableofcontents %Esta línea genera un indice a partir de las secciones y subsecciones creadas en el documento
	\newpage

	\section{Objetivos}
		Familiarizarse con las técnicas y herramientas de profiling y optimización de software, implementando y optimizando un programa que busca descubrir
las contraseñas hasheadas en un archivo.

		\vspace{1cm}
 	\section{Introducción Teórica}
		\label{sec:InfoTeo}
  A continuación se explican brevemente los conceptos necesarios para llevar a cabo esta tarea:

  \vspace{0.5cm}

	\subsection{Time}
		El comando time permite realizar mediciones en relación al tiempo de ejecución de un programa. Al ejecutar el comando sin opciones, 
		seguido del nombre de un programa y su lista de argumentos:
		\begin{verbatim}
			     time unPrograma arg1 arg2
		\end{verbatim}
		se muestra por pantalla una serie de tiempos, de esta manera:
		\begin{verbatim}
			     real	0m0.137s
			     user	0m0.120s
			     sys	0m0.030s
		\end{verbatim}
                Donde:
                \begin{itemize}
                  \item \textbf{real} es el ``tiempo de reloj'' que toma la ejecución, desde que empieza hasta que termina, incluyendo lapsos utilizados por otros procesos, o durante los cuales el programa está bloqueado esperando I/O.
                  \item \textbf{user} es el tiempo que el código pasa en modo usuario, por ejemplo, ejecutando código de bibliotecas. Sólo tiene en cuenta el tiempo en el que el proceso se está ejecutando.
                  \item \textbf{sys} es el tiempo que el código pasa en el kernel, por ejemplo, haciendo llamadas al sistema. Como el caso anterior, sólo tiene en cuenta el tiempo en el que el proceso se está ejecutando.
                \end{itemize}

                Es decir que para conocer el tiempo de CPU que verdaderamente consume el programa, hay que sumar los tiempos \emph{user} y \emph{sys}.

		\vspace{0.5cm}
	\subsection{Gprof}
		Gprof es un programa que permite conocer información de utilidad sobre el rendimiento de un programa en C. A efectos de este trabajo práctico en particular, nos interesa saber el tiempo de ejecución consumido por cada función del programa.

Para utilizar gprof se debe compilar el código con gcc, con la opción -pg:
                \begin{verbatim}
                gcc -pg -o unPrograma unPrograma.c
                \end{verbatim}
                Una vez compilado, se debe ejecutar el programa normalmente. Esto generará el archivo ``gmon.out'' en el mismo directorio donde está el ejecutable. Finalmente, al ejecutar gprof de la siguiente manera:
                \begin{verbatim}
                gprof unPrograma > reporte.txt
                \end{verbatim}
                se genera el reporte con la información de rendimiento y se almacena en un archivo de texto.

		\vspace{0.5cm}


	\subsection{Ley de Amdahl}
		La ganancia en desempeño que puede ser obtenida mejorando una parte de un programa puede ser calculada utilizando la ley de Amdahl.
		Esta ley dice que la ganancia en desempeño obtenida utilizando una mejora está limitada por la fracción de tiempo en que esta mejora puede ser utilizada.\\
		La ley de Amdahl define el \emph{speedup} que puede obtenerse una mejora en particular. Que es \emph{speedup}? Supongamos que podemos hacerle una mejora 
		a un programa que incrementará su desempeño cuando esta sea utilizada, entonces el \emph{speedup} es\\\\
		$Speedup \:= \:\frac{Desempe\tilde{n}o \:para \:la \:tarea \:completa \:utilizando \:la \:mejora \:cuando \:sea \:posible}{Desempe\tilde{n}o \:de \:la \:tarea \:completa \:sin \:usar \:la \:mejora}$\\\\
		Alternativamente,\\\\
		$Speedup \:= \:\frac{Tiempo \:de \:ejecuci\acute{o}n \:para \:la \:tarea \:completa \:sin \:la \:mejora}{Tiempo \:de \:ejecuci\acute{o}n \:de \:la \:tarea \:completa \:utilizando \:la \:mejora \:cuando \:sea \:posible}$\\\\
		El \emph{speedup} nos dice cuanto más rapido un programa se ejecutará usando el programa con la mejora en contraposición al programa original.
		
		\vspace{1cm}
					
	\section{Desarrollo}
		
		\vspace{0.5cm}
		\subsection{Modo de Operación}
			
		
		
		\subsection{Ejemplos}
               
		     
	\section{Implementación Original}
	  \subsection{Código Fuente tp2.c}
\begin{scriptsize}
\begin{Verbatim}
#include "md5.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void get_sum(char *input, char *output);
void get_pwd(char* hash, int cantchar) {
	char *output;
	char *input;
	int i,j,k,l;
	
	input = (char*) malloc(5);
	input[4] = 0;
	output = (char *) malloc(33);
	for ( l = 0; l < 256; l++) 
		for ( k = 0; k < 256; k++) 
			for ( j = 0; j < 256; j++) 
				for ( i = 0; i < 256; i++){
					input[0] = (char) i;
					input[1] = (char) j;
					input[2] = (char) k;
					input[3] = (char) l;
					//printf("Input: %s", input);
					get_sum(input, output);
					if (strcmp(output,hash) == 0) {
						printf ("Hash: %s Contraseña: %.*s\n", hash, cantchar, input);
						return;
					}
				}
}

int main (int argc, char **argv) {
	char *arch = (char *) argv[1];
	char* hash;
	FILE* archivo;
	int cantchar;

	if (strcmp(arch, "passwd_1") == 0)
		cantchar = 1;
	if (strcmp(arch, "passwd_2") == 0)
		cantchar = 2;
	if (strcmp(arch, "passwd_3") == 0)
		cantchar = 3;
	if (strcmp(arch, "passwd_4") == 0)
		cantchar = 1;
	hash = (char*) malloc(33);
	archivo = fopen(arch,"r");
	while (!feof(archivo)) {		
		if (fread(hash, 1, 33, archivo) == 33) {
			hash[32]='\0';
			get_pwd(hash, cantchar);
		}
	}
	return 0;
}
\end{Verbatim}
\end{scriptsize}


\subsection{Código get\_sum.c}


\begin{scriptsize}
\begin{Verbatim}
#include "md5.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void get_sum(char *input, char *output)
{	
	int i;
	MD5_CTX contexto;
	unsigned char *buffer = (unsigned char *) malloc(17);
	MD5_Init(&contexto);
	MD5_Update(&contexto, input, strlen(input));
	MD5_Final(buffer, &contexto);
	*output=0;
	for (i=0;i<16;i++)
	{
		sprintf(output,"%s%02x",output, buffer[i]);
	}
}
\end{Verbatim}
\end{scriptsize}


\subsection{Código md5.c}
\begin{scriptsize}
\begin{Verbatim}
/*
 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
 * MD5 Message-Digest Algorithm (RFC 1321).
 *
 * Homepage:
 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
 *
 * Author:
 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
 *
 * This software was written by Alexander Peslyak in 2001.  No copyright is
 * claimed, and the software is hereby placed in the public domain.
 * In case this attempt to disclaim copyright and place the software in the
 * public domain is deemed null and void, then the software is
 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
 * general public under the following terms:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted.
 *
 * There's ABSOLUTELY NO WARRANTY, express or implied.
 *
 * (This is a heavily cut-down "BSD license".)
 *
 * This differs from Colin Plumb's older public domain implementation in that
 * no exactly 32-bit integer data type is required (any 32-bit or wider
 * unsigned integer data type will do), there's no compile-time endianness
 * configuration, and the function prototypes match OpenSSL's.  No code from
 * Colin Plumb's implementation has been reused; this comment merely compares
 * the properties of the two independent implementations.
 *
 * The primary goals of this implementation are portability and ease of use.
 * It is meant to be fast, but not as fast as possible.  Some known
 * optimizations are not included to reduce source code size and avoid
 * compile-time configuration.
 */

#ifndef HAVE_OPENSSL

#include <string.h>

#include "md5.h"

/*
 * The basic MD5 functions.
 *
 * F and G are optimized compared to their RFC 1321 definitions for
 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
 * implementation.
 */
#define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z)			(((x) ^ (y)) ^ (z))
#define H2(x, y, z)			((x) ^ ((y) ^ (z)))
#define I(x, y, z)			((y) ^ ((x) | ~(z)))

/*
 * The MD5 transformation for all four rounds.
 */
#define STEP(f, a, b, c, d, x, t, s) \
	(a) += f((b), (c), (d)) + (x) + (t); \
	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
	(a) += (b);

/*
 * SET reads 4 input bytes in little-endian byte order and stores them
 * in a properly aligned word in host byte order.
 *
 * The check for little-endian architectures that tolerate unaligned
 * memory accesses is just an optimization.  Nothing will break if it
 * doesn't work.
 */
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define SET(n) \
	(*(MD5_u32plus *)&ptr[(n) * 4])
#define GET(n) \
	SET(n)
#else
#define SET(n) \
	(ctx->block[(n)] = \
	(MD5_u32plus)ptr[(n) * 4] | \
	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define GET(n) \
	(ctx->block[(n)])
#endif

/*
 * This processes one or more 64-byte data blocks, but does NOT update
 * the bit counters.  There are no alignment requirements.
 */
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
	const unsigned char *ptr;
	MD5_u32plus a, b, c, d;
	MD5_u32plus saved_a, saved_b, saved_c, saved_d;

	ptr = (const unsigned char *)data;

	a = ctx->a;
	b = ctx->b;
	c = ctx->c;
	d = ctx->d;

	do {
		saved_a = a;
		saved_b = b;
		saved_c = c;
		saved_d = d;

/* Round 1 */
		STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
		STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
		STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
		STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
		STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
		STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
		STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
		STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
		STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
		STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
		STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
		STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
		STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
		STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
		STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
		STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)

/* Round 2 */
		STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
		STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
		STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
		STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
		STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
		STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
		STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
		STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
		STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
		STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
		STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
		STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
		STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
		STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
		STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
		STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)

/* Round 3 */
		STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
		STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
		STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
		STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
		STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
		STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
		STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
		STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
		STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
		STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
		STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
		STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
		STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
		STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
		STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
		STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)

/* Round 4 */
		STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
		STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
		STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
		STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
		STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
		STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
		STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
		STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
		STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
		STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
		STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
		STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
		STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
		STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
		STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
		STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)

		a += saved_a;
		b += saved_b;
		c += saved_c;
		d += saved_d;

		ptr += 64;
	} while (size -= 64);

	ctx->a = a;
	ctx->b = b;
	ctx->c = c;
	ctx->d = d;

	return ptr;
}

void MD5_Init(MD5_CTX *ctx)
{
	ctx->a = 0x67452301;
	ctx->b = 0xefcdab89;
	ctx->c = 0x98badcfe;
	ctx->d = 0x10325476;

	ctx->lo = 0;
	ctx->hi = 0;
}

void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
	MD5_u32plus saved_lo;
	unsigned long used, available;

	saved_lo = ctx->lo;
	if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
		ctx->hi++;
	ctx->hi += size >> 29;

	used = saved_lo & 0x3f;

	if (used) {
		available = 64 - used;

		if (size < available) {
			memcpy(&ctx->buffer[used], data, size);
			return;
		}

		memcpy(&ctx->buffer[used], data, available);
		data = (const unsigned char *)data + available;
		size -= available;
		body(ctx, ctx->buffer, 64);
	}

	if (size >= 64) {
		data = body(ctx, data, size & ~(unsigned long)0x3f);
		size &= 0x3f;
	}

	memcpy(ctx->buffer, data, size);
}

void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
	unsigned long used, available;

	used = ctx->lo & 0x3f;

	ctx->buffer[used++] = 0x80;

	available = 64 - used;

	if (available < 8) {
		memset(&ctx->buffer[used], 0, available);
		body(ctx, ctx->buffer, 64);
		used = 0;
		available = 64;
	}

	memset(&ctx->buffer[used], 0, available - 8);

	ctx->lo <<= 3;
	ctx->buffer[56] = ctx->lo;
	ctx->buffer[57] = ctx->lo >> 8;
	ctx->buffer[58] = ctx->lo >> 16;
	ctx->buffer[59] = ctx->lo >> 24;
	ctx->buffer[60] = ctx->hi;
	ctx->buffer[61] = ctx->hi >> 8;
	ctx->buffer[62] = ctx->hi >> 16;
	ctx->buffer[63] = ctx->hi >> 24;

	body(ctx, ctx->buffer, 64);

	result[0] = ctx->a;
	result[1] = ctx->a >> 8;
	result[2] = ctx->a >> 16;
	result[3] = ctx->a >> 24;
	result[4] = ctx->b;
	result[5] = ctx->b >> 8;
	result[6] = ctx->b >> 16;
	result[7] = ctx->b >> 24;
	result[8] = ctx->c;
	result[9] = ctx->c >> 8;
	result[10] = ctx->c >> 16;
	result[11] = ctx->c >> 24;
	result[12] = ctx->d;
	result[13] = ctx->d >> 8;
	result[14] = ctx->d >> 16;
	result[15] = ctx->d >> 24;

	memset(ctx, 0, sizeof(*ctx));
}

#endif
\end{Verbatim}
\end{scriptsize}


\subsection{Código md5.h}
\begin{scriptsize}
\begin{Verbatim}
/*
 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
 * MD5 Message-Digest Algorithm (RFC 1321).
 *
 * Homepage:
 * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
 *
 * Author:
 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
 *
 * This software was written by Alexander Peslyak in 2001.  No copyright is
 * claimed, and the software is hereby placed in the public domain.
 * In case this attempt to disclaim copyright and place the software in the
 * public domain is deemed null and void, then the software is
 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
 * general public under the following terms:
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted.
 *
 * There's ABSOLUTELY NO WARRANTY, express or implied.
 *
 * See md5.c for more information.
 */

#ifdef HAVE_OPENSSL
#include <openssl/md5.h>
#elif !defined(_MD5_H)
#define _MD5_H

/* Any 32-bit or wider unsigned integer data type will do */
typedef unsigned int MD5_u32plus;

typedef struct {
	MD5_u32plus lo, hi;
	MD5_u32plus a, b, c, d;
	unsigned char buffer[64];
	MD5_u32plus block[16];
} MD5_CTX;

extern void MD5_Init(MD5_CTX *ctx);
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);

#endif
\end{Verbatim}
\end{scriptsize}

\section{Contraseñas descubiertas}
\subsection{Archivo passwd\_1}
\begin{verbatim}
$ ./tp2 passwd_1
Hash: 0cc175b9c0f1b6a831c399e269772661 Contraseña: a
Hash: 92eb5ffee6ae2fec3ad71c777531578f Contraseña: b
Hash: 4a8a08f09d37b73795649038408b5f33 Contraseña: c
Hash: 8277e0910d750195b448797616e091ad Contraseña: d
Hash: cfcd208495d565ef66e7dff9f98764da Contraseña: 0
Hash: c4ca4238a0b923820dcc509a6f75849b Contraseña: 1
Hash: c81e728d9d4c2f636f067f89cc14862c Contraseña: 2
Hash: eccbc87e4b5ce2fe28308fd9f2a7baf3 Contraseña: 3
Hash: fbade9e36a3f36d3d676c1b808451dd7 Contraseña: z
Hash: 83878c91171338902e0fe0fb97a8c47a Contraseña: p
Hash: 7694f4a66316e53c8cdd9d9954bd611d Contraseña: q
\end{verbatim}
\subsection{Archivo passwd\_2}
\begin{verbatim}
$ ./tp2 passwd_2
Hash: 187ef4436122d1cc2f40dc2b92f0eba0 Contraseña: ab
Hash: 6865aeb3a9ed28f9a79ec454b259e5d0 Contraseña: cd
Hash: feb78cc258bdc76867354f01c22dbe43 Contraseña: ef
Hash: eab71244afb687f16d8c4f5ee9d6ef0e Contraseña: nn
Hash: e6c760b3216a51c656c5861d72d5bf62 Contraseña: zx
Hash: 43ec517d68b6edd3015b3edc9a11367b Contraseña: 81
Hash: 1f0e3dad99908345f7439f8ffabdffc4 Contraseña: 19
Hash: 68d30a9594728bc39aa24be94b319d21 Contraseña: 84
Hash: 25ed1bcb423b0b7200f485fc5ff71c8e Contraseña: zz
Hash: 3817848ef191468810fc4b1cfc855ba1 Contraseña: tp
Hash: 382da15dfcfa571b3973cb5ae2223f76 Contraseña: pq
\end{verbatim}
\subsection{Archivo passwd\_3}
\begin{verbatim}
$ ./tp2 passwd_3
Hash: 807d88d96b6abc18f4fd812af6ffc8df Contraseña: Iha
Hash: 2fe585b232995699edf68a537f91d31d Contraseña: vet
Hash: 79e13729560b7d91e8ba4f8a141af42b Contraseña: hef
Hash: 874009492fa91f511e7e775ecfbc28d6 Contraseña: eel
Hash: d4408643ccbd7e83d0c54f42e405d618 Contraseña: ing
Hash: c9d7c016f77bb9c9c4e73198971f9448 Contraseña: Som
Hash: 16583432f50078f8532b86c0f458d3ba Contraseña: ebo
Hash: a851e45c1daa1d762f2500f9d0ab0700 Contraseña: dys
Hash: 611c59af56268df5534fef5bc3c37b1d Contraseña: wat
Hash: 1e6086b705c7161eeb93a8b249a5ca7c Contraseña: chi
Hash: 1ff4d60d97c7c4d298d0e2f130d48da3 Contraseña: ngm
\end{verbatim}
\subsection{Archivo passwd\_4}
\begin{verbatim}
$ ./tp2 passwd_4
Hash: 6b6f315d621b5b0ce58a743c15f6fcaa Contraseña: a
Hash: d4bdc65976ab683ad32a187c724f54b7 Contraseña: b
Hash: 6abebdfdca07899fbd010cbdcbeb363f Contraseña: c
Hash: 36f84d93f935db1cee88ad0492961fb7 Contraseña: d
Hash: 157b1b1a0772d1c0d50be27e224d576d Contraseña: 0
Hash: f854d35247f3b14c3257f33b674411e8 Contraseña: 1
Hash: b1f1298ffb25acf6de2a38d9063886c1 Contraseña: 2
Hash: d259c8557ce90de7d742e497639bfde4 Contraseña: 3
Hash: 2762be8fee1bf6f319878fecb4363f7f Contraseña: z
Hash: 74b2cd41be6aa4fada1ed714e559ebde Contraseña: p
Hash: 26a6f36dc100ff2aba830bb5719e8236 Contraseña: q
\end{verbatim}

\section{Resultados Profiling Programa Original}
\subsection{Archivo passwd\_1}
\begin{verbatim}
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  Ts/call  Ts/call  name    
  0.00      0.00     0.00      950     0.00     0.00  MD5_Final
  0.00      0.00     0.00      950     0.00     0.00  MD5_Init
  0.00      0.00     0.00      950     0.00     0.00  MD5_Update
  0.00      0.00     0.00      950     0.00     0.00  body
  0.00      0.00     0.00      950     0.00     0.00  get_sum
  0.00      0.00     0.00       11     0.00     0.00  get_pwd
\end{verbatim}
\subsection{Archivo passwd\_2}
\begin{verbatim}
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 70.10      0.14     0.14   266011     0.00     0.00  body
 15.02      0.17     0.03   266011     0.00     0.00  MD5_Final
 10.01      0.19     0.02   266011     0.00     0.00  get_sum
  5.01      0.20     0.01   266011     0.00     0.00  MD5_Update
  0.00      0.20     0.00   266011     0.00     0.00  MD5_Init
  0.00      0.20     0.00       11     0.00    18.21  get_pwd
\end{verbatim}
\subsection{Archivo passwd\_3}
\begin{verbatim}
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 78.49     36.52    36.52 78349156     0.00     0.00  body
 13.20     42.66     6.14 78349156     0.00     0.00  get_sum
  4.97     44.98     2.31 78349156     0.00     0.00  MD5_Final
  1.64     45.74     0.76 78349156     0.00     0.00  MD5_Update
  1.11     46.25     0.52 78349156     0.00     0.00  MD5_Init
  0.58     46.52     0.27       11     0.02     4.23  get_pwd
  0.01     46.53     0.01                             frame_dummy
\end{verbatim}
\subsection{Archivo passwd\_4}
\begin{verbatim}
  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name    
 76.45     40.27    40.27 87567286     0.00     0.00  body
 14.28     47.79     7.52 87567286     0.00     0.00  get_sum
  6.11     51.01     3.22 87567286     0.00     0.00  MD5_Final
  1.53     51.82     0.81 87567286     0.00     0.00  MD5_Update
  1.05     52.38     0.56 87567286     0.00     0.00  MD5_Init
  0.57     52.68     0.30       11     0.03     4.79  get_pwd
\end{verbatim}

\section{Tiempos Programa Original}
\subsection{Archivo passwd\_1}
\begin{verbatim}
$ time ./tp2 passwd_1
Hash: 0cc175b9c0f1b6a831c399e269772661 Contraseña: a
Hash: 92eb5ffee6ae2fec3ad71c777531578f Contraseña: b
Hash: 4a8a08f09d37b73795649038408b5f33 Contraseña: c
Hash: 8277e0910d750195b448797616e091ad Contraseña: d
Hash: cfcd208495d565ef66e7dff9f98764da Contraseña: 0
Hash: c4ca4238a0b923820dcc509a6f75849b Contraseña: 1
Hash: c81e728d9d4c2f636f067f89cc14862c Contraseña: 2
Hash: eccbc87e4b5ce2fe28308fd9f2a7baf3 Contraseña: 3
Hash: fbade9e36a3f36d3d676c1b808451dd7 Contraseña: z
Hash: 83878c91171338902e0fe0fb97a8c47a Contraseña: p
Hash: 7694f4a66316e53c8cdd9d9954bd611d Contraseña: q

real	0m0.015s
user	0m0.008s
sys	0m0.004s
\end{verbatim}
\subsection{Archivo passwd\_2}
\begin{verbatim}
$ time ./tp2 passwd_2
Hash: 187ef4436122d1cc2f40dc2b92f0eba0 Contraseña: ab
Hash: 6865aeb3a9ed28f9a79ec454b259e5d0 Contraseña: cd
Hash: feb78cc258bdc76867354f01c22dbe43 Contraseña: ef
Hash: eab71244afb687f16d8c4f5ee9d6ef0e Contraseña: nn
Hash: e6c760b3216a51c656c5861d72d5bf62 Contraseña: zx
Hash: 43ec517d68b6edd3015b3edc9a11367b Contraseña: 81
Hash: 1f0e3dad99908345f7439f8ffabdffc4 Contraseña: 19
Hash: 68d30a9594728bc39aa24be94b319d21 Contraseña: 84
Hash: 25ed1bcb423b0b7200f485fc5ff71c8e Contraseña: zz
Hash: 3817848ef191468810fc4b1cfc855ba1 Contraseña: tp
Hash: 382da15dfcfa571b3973cb5ae2223f76 Contraseña: pq

real	0m0.717s
user	0m0.708s
sys	0m0.004s
\end{verbatim}
\subsection{Archivo passwd\_3}
\begin{verbatim}
$ time ./tp2 passwd_3
Hash: 807d88d96b6abc18f4fd812af6ffc8df Contraseña: Iha
Hash: 2fe585b232995699edf68a537f91d31d Contraseña: vet
Hash: 79e13729560b7d91e8ba4f8a141af42b Contraseña: hef
Hash: 874009492fa91f511e7e775ecfbc28d6 Contraseña: eel
Hash: d4408643ccbd7e83d0c54f42e405d618 Contraseña: ing
Hash: c9d7c016f77bb9c9c4e73198971f9448 Contraseña: Som
Hash: 16583432f50078f8532b86c0f458d3ba Contraseña: ebo
Hash: a851e45c1daa1d762f2500f9d0ab0700 Contraseña: dys
Hash: 611c59af56268df5534fef5bc3c37b1d Contraseña: wat
Hash: 1e6086b705c7161eeb93a8b249a5ca7c Contraseña: chi
Hash: 1ff4d60d97c7c4d298d0e2f130d48da3 Contraseña: ngm

real	3m25.228s
user	3m24.201s
sys	0m0.696s

\end{verbatim}
\subsection{Archivo passwd\_4}
\begin{verbatim}
$ time ./tp2 passwd_4
Hash: 6b6f315d621b5b0ce58a743c15f6fcaa Contraseña: a
Hash: d4bdc65976ab683ad32a187c724f54b7 Contraseña: b
Hash: 6abebdfdca07899fbd010cbdcbeb363f Contraseña: c
Hash: 36f84d93f935db1cee88ad0492961fb7 Contraseña: d
Hash: 157b1b1a0772d1c0d50be27e224d576d Contraseña: 0
Hash: f854d35247f3b14c3257f33b674411e8 Contraseña: 1
Hash: b1f1298ffb25acf6de2a38d9063886c1 Contraseña: 2
Hash: d259c8557ce90de7d742e497639bfde4 Contraseña: 3
Hash: 2762be8fee1bf6f319878fecb4363f7f Contraseña: z
Hash: 74b2cd41be6aa4fada1ed714e559ebde Contraseña: p
Hash: 26a6f36dc100ff2aba830bb5719e8236 Contraseña: q

real	3m49.297s
user	3m48.274s
sys	0m0.656s
\end{verbatim}

\section{Programa Mejorado}
\section{Resultados Profiling Programa Mejorado}
\section{Tiempos Programa Mejorado}

\section{Conclusiones}



\end{document}
